aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorNeelesh Gupta <neelegup@linux.vnet.ibm.com>2014-12-13 13:01:05 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2014-12-13 20:44:46 -0500
commit470834508f87877f680738a10a305280582c7aed (patch)
tree62cf343202cd77e25285d164bad5c5f6c0bc4877 /arch/powerpc
parent63f13448d81c910a284b096149411a719cbed501 (diff)
i2c: Driver to expose PowerNV platform i2c busses
The patch exposes the available i2c busses on the PowerNV platform to the kernel and implements the bus driver to support i2c and smbus commands. The driver uses the platform device infrastructure to probe the busses on the platform and registers them with the i2c driver framework. Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Wolfram Sang <wsa@the-dreams.de> (I2C part, excluding the bindings) Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/opal.h29
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S1
-rw-r--r--arch/powerpc/platforms/powernv/opal.c12
3 files changed, 42 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 5cd8d2fddba9..4095749c973f 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -56,6 +56,14 @@ struct opal_sg_list {
56#define OPAL_HARDWARE_FROZEN -13 56#define OPAL_HARDWARE_FROZEN -13
57#define OPAL_WRONG_STATE -14 57#define OPAL_WRONG_STATE -14
58#define OPAL_ASYNC_COMPLETION -15 58#define OPAL_ASYNC_COMPLETION -15
59#define OPAL_I2C_TIMEOUT -17
60#define OPAL_I2C_INVALID_CMD -18
61#define OPAL_I2C_LBUS_PARITY -19
62#define OPAL_I2C_BKEND_OVERRUN -20
63#define OPAL_I2C_BKEND_ACCESS -21
64#define OPAL_I2C_ARBT_LOST -22
65#define OPAL_I2C_NACK_RCVD -23
66#define OPAL_I2C_STOP_ERR -24
59 67
60/* API Tokens (in r0) */ 68/* API Tokens (in r0) */
61#define OPAL_INVALID_CALL -1 69#define OPAL_INVALID_CALL -1
@@ -158,6 +166,7 @@ struct opal_sg_list {
158#define OPAL_READ_TPO 104 166#define OPAL_READ_TPO 104
159#define OPAL_IPMI_SEND 107 167#define OPAL_IPMI_SEND 107
160#define OPAL_IPMI_RECV 108 168#define OPAL_IPMI_RECV 108
169#define OPAL_I2C_REQUEST 109
161 170
162#ifndef __ASSEMBLY__ 171#ifndef __ASSEMBLY__
163 172
@@ -712,6 +721,24 @@ typedef struct oppanel_line {
712 uint64_t line_len; 721 uint64_t line_len;
713} oppanel_line_t; 722} oppanel_line_t;
714 723
724/* OPAL I2C request */
725struct opal_i2c_request {
726 uint8_t type;
727#define OPAL_I2C_RAW_READ 0
728#define OPAL_I2C_RAW_WRITE 1
729#define OPAL_I2C_SM_READ 2
730#define OPAL_I2C_SM_WRITE 3
731 uint8_t flags;
732#define OPAL_I2C_ADDR_10 0x01 /* Not supported yet */
733 uint8_t subaddr_sz; /* Max 4 */
734 uint8_t reserved;
735 __be16 addr; /* 7 or 10 bit address */
736 __be16 reserved2;
737 __be32 subaddr; /* Sub-address if any */
738 __be32 size; /* Data size */
739 __be64 buffer_ra; /* Buffer real address */
740};
741
715/* /sys/firmware/opal */ 742/* /sys/firmware/opal */
716extern struct kobject *opal_kobj; 743extern struct kobject *opal_kobj;
717 744
@@ -881,6 +908,8 @@ int64_t opal_ipmi_send(uint64_t interface, struct opal_ipmi_msg *msg,
881 uint64_t msg_len); 908 uint64_t msg_len);
882int64_t opal_ipmi_recv(uint64_t interface, struct opal_ipmi_msg *msg, 909int64_t opal_ipmi_recv(uint64_t interface, struct opal_ipmi_msg *msg,
883 uint64_t *msg_len); 910 uint64_t *msg_len);
911int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
912 struct opal_i2c_request *oreq);
884 913
885/* Internal functions */ 914/* Internal functions */
886extern int early_init_dt_scan_opal(unsigned long node, const char *uname, 915extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 0a299be588af..2111e08d406b 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -254,3 +254,4 @@ OPAL_CALL(opal_tpo_write, OPAL_WRITE_TPO);
254OPAL_CALL(opal_tpo_read, OPAL_READ_TPO); 254OPAL_CALL(opal_tpo_read, OPAL_READ_TPO);
255OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND); 255OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND);
256OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV); 256OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV);
257OPAL_CALL(opal_i2c_request, OPAL_I2C_REQUEST);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index cb0b6de79cd4..aa316d820736 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -653,6 +653,14 @@ static void opal_ipmi_init(struct device_node *opal_node)
653 of_platform_device_create(np, NULL, NULL); 653 of_platform_device_create(np, NULL, NULL);
654} 654}
655 655
656static void opal_i2c_create_devs(void)
657{
658 struct device_node *np;
659
660 for_each_compatible_node(np, NULL, "ibm,opal-i2c")
661 of_platform_device_create(np, NULL, NULL);
662}
663
656static int __init opal_init(void) 664static int __init opal_init(void)
657{ 665{
658 struct device_node *np, *consoles; 666 struct device_node *np, *consoles;
@@ -679,6 +687,9 @@ static int __init opal_init(void)
679 of_node_put(consoles); 687 of_node_put(consoles);
680 } 688 }
681 689
690 /* Create i2c platform devices */
691 opal_i2c_create_devs();
692
682 /* Find all OPAL interrupts and request them */ 693 /* Find all OPAL interrupts and request them */
683 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); 694 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
684 pr_debug("opal: Found %d interrupts reserved for OPAL\n", 695 pr_debug("opal: Found %d interrupts reserved for OPAL\n",
@@ -824,3 +835,4 @@ EXPORT_SYMBOL_GPL(opal_rtc_read);
824EXPORT_SYMBOL_GPL(opal_rtc_write); 835EXPORT_SYMBOL_GPL(opal_rtc_write);
825EXPORT_SYMBOL_GPL(opal_tpo_read); 836EXPORT_SYMBOL_GPL(opal_tpo_read);
826EXPORT_SYMBOL_GPL(opal_tpo_write); 837EXPORT_SYMBOL_GPL(opal_tpo_write);
838EXPORT_SYMBOL_GPL(opal_i2c_request);